home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 1.iso
/
desktop
/
gv21.zip
/
FILE.C
next >
Wrap
C/C++ Source or Header
|
1995-03-28
|
77KB
|
2,885 lines
/* 'FILE.C' DLL for Graphics Viewer
Written by: Joe C. Oliphant
CompuServe 71742, 1451
E-Mail joe_oliphant@csufresno.edu
*/
#include "windows.h"
#include "stdio.h"
#include "io.h"
#include "stdlib.h"
#include "string.h"
#include "malloc.h"
#define NO_OPEN -1
#define MEM_ERR -2
#define BAD_READ -3
#define BAD_COPY -4
#define NO_BHND -5
#define NO_GPTR -6
#define BAD_CODE -7
#define BAD_FIRST -8
#define BAD_BIT -9
#define BAD_HEAD -10
#define NO_BMP -11
#define NO_PAL -12
#define pixels2bytes(n) ((n + 7) / 8)
BITMAPINFOHEADER bmp;
typedef struct {
unsigned char id[2];
long filesize;
int reserved[2];
long headersize;
} BMPHEAD;
BMPHEAD bmh;
typedef struct {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
} SBITMAPINFO;
SBITMAPINFO bmpi;
typedef struct QCOLOR {
unsigned char RGB[3];
unsigned char newcolorindex;
unsigned long count;
struct QCOLOR far *pnext;
} QCOLOR;
typedef struct {
unsigned char RGBmin[3], RGBwidth[3];
unsigned int numentries;
unsigned long count;
QCOLOR far *quantizedcolors;
} NEWCOLOR;
typedef struct {
unsigned char sig[6];
unsigned int screenwidth, screenheight;
unsigned char flags, background, aspect;
} GIFHEAD;
GIFHEAD gif;
typedef struct {
unsigned int left, top, width, height;
unsigned char flags;
} IMAGEBLOCK;
IMAGEBLOCK iblk;
typedef struct {
unsigned int w,h;
unsigned int x,y;
unsigned char nPlanes;
unsigned char masking;
unsigned char compression;
unsigned char pad1;
unsigned int transparentColor;
unsigned char xAspect,yAspect;
unsigned int pageW,pageH;
} IFFHEAD;
IFFHEAD iff;
typedef struct {
unsigned char key[3];
unsigned char flag;
unsigned char pad1;
unsigned char bits;
unsigned char pad2[2];
unsigned char name[4];
unsigned int width, height;
} IMGHEAD;
IMGHEAD img;
typedef struct {
unsigned char zerobyte;
unsigned char name[64];
unsigned char type[4];
} MACHEAD;
MACHEAD mac;
typedef struct {
unsigned int key1, key2;
unsigned int width, height;
} MSPHEAD;
MSPHEAD msp;
typedef struct {
unsigned char manufacturer;
unsigned char version;
unsigned char encoding;
unsigned char bits;
unsigned int xmin, ymin;
unsigned int xmax, ymax;
unsigned int hres;
unsigned int vres;
unsigned char palette[48];
unsigned char reserved;
unsigned char color_planes;
unsigned int bytes_per_line;
unsigned int palette_type;
unsigned char filler[58];
} PCXHEAD;
PCXHEAD pcx;
typedef struct {
unsigned int mark;
unsigned int xsize, ysize;
unsigned int xoff, yoff;
unsigned char bitsinf;
unsigned char emark;
unsigned char evideo;
unsigned int edesc;
unsigned int esize;
} PICHEAD;
PICHEAD pic;
typedef struct {
unsigned int pbsize;
unsigned int bsize;
unsigned char mbyte;
} PICBLOCK;
PICBLOCK pbk;
typedef struct {
unsigned char identsize;
unsigned char colormaptype;
unsigned char imagetype;
unsigned int colormapstart;
unsigned int colormaplength;
unsigned char colormapbits;
unsigned int xstart;
unsigned int ystart;
unsigned int width, depth;
unsigned char bits;
unsigned char descriptor;
} TGAHEAD;
TGAHEAD tga;
typedef struct {
unsigned char id[4];
unsigned long start;
unsigned char product;
unsigned char filetype;
unsigned char majorversion;
unsigned char minorversion;
unsigned int encrypt;
unsigned int reserved;
} WPGHEAD;
WPGHEAD wpg;
static char picbits;
static int linewidth;
static int sortRGBaxis;
unsigned char path[81];
unsigned char palette[768];
unsigned char tmppalette[768];
unsigned char masktable[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char bittable[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char buf[255];
GLOBALHANDLE ghnd;
GLOBALHANDLE dh;
int SetLine(void);
int Display(unsigned char huge *gptr, HDC pichdc, HWND pichwnd, int dither,
int print, int x, int y, int scale);
int Quantize(unsigned char huge *gptr, int far *colorcount,
char *outputcolormap);
int DivideMap(NEWCOLOR far *newcolorsubdiv, int colormapsize,
int far *newcolormapsize, char huge *lpstr);
void psort(char far * far *array, int number);
void pinsert(char far * far *array, int number);
int DitherPicture(unsigned char huge *gptr);
long motr2intellng(long ml, int tf);
int motr2intelint(int ml, int tf);
unsigned int GetMIw(FILE *fp, int tf);
unsigned long GetMIlng(FILE *fp, int tf);
int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine) {
if(wHeapSize > 0)
UnlockData(0);
return(1);
}
HBITMAP FAR PASCAL ReadART(LPSTR fname, HDC pichdc, HWND pichwnd,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int j;
char *line;
long bufsize;
unsigned char huge *gptr;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if(getw(fp) != 0) return(BAD_HEAD);
bmp.biWidth = getw(fp);
getw(fp);
bmp.biHeight = getw(fp);
bmp.biBitCount = picbits = 1;
linewidth = SetLine();
memset(palette, 0, 768);
memcpy(palette, "\000\000\000\377\377\377", 6);
if((line = malloc(linewidth)) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
GlobalFree(ghnd);
return(NO_GPTR);
}
for (j = 0; j < bmp.biHeight; ++j) {
fread(line, 1, linewidth, fp);
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, 0, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadBMP(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
unsigned int c, d, e, f, h, hf, j, l, n;
long compress, bufsize;
char *line;
char huge *gptr;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if(fread((char *)&bmh,1,sizeof(BMPHEAD),fp) != sizeof(BMPHEAD) ||
_fmemcmp(bmh.id, "BM", 2)) {
fclose(fp);
return(BAD_HEAD);
}
if(fread((char *)&bmp,1,sizeof(BITMAPINFOHEADER),fp) != sizeof(BITMAPINFOHEADER)) {
fclose(fp);
return(BAD_HEAD);
}
if(bmp.biSize != 12) compress = bmp.biCompression;
linewidth = SetLine();
if(bmp.biSize == 12) fseek(fp, 26, SEEK_SET);
memset(palette, 0, 768);
if(bmp.biBitCount == 1) memcpy(palette, "\000\000\000\377\377\377", 6);
if(bmp.biBitCount == 4 || bmp.biBitCount == 8) {
n = 1 << bmp.biBitCount;
for(j = 0; j < n; ++j) {
palette[j * 3 + 2] = fgetc(fp);
palette[j * 3 + 1] = fgetc(fp);
palette[j * 3] = fgetc(fp);
if(bmp.biSize != 12) fgetc(fp);
}
}
if((line = malloc(linewidth)) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
GlobalFree(ghnd);
return(NO_GPTR);
}
fseek(fp, bmh.headersize, SEEK_SET);
for(j = bmp.biHeight - 1; j != -1; j--) {
if(compress == BI_RGB)
fread(line, 1, linewidth, fp);
if(compress == BI_RLE4) {
n = 0;
hf = FALSE;
memset(line, 0, linewidth);
do {
c = fgetc(fp);
d = fgetc(fp);
if(c == 0) {
if(d == 0 || d == 1) break;
if(d > 2) {
e = (d >> 1);
while(e--) {
f = fgetc(fp);
h = f & 0xf0;
l = f & 0x0f;
if(hf) {
line[n++] |= (h >> 4);
line[n] = (l << 4);
}
else line[n++] = f;
}
if(d & 0x01) {
if(hf) {
line[n++] |= (h >> 4);
hf = FALSE;
}
else {
line[n] = h;
hf = TRUE;
}
}
if(ftell(fp) & 1) fgetc(fp);
}
}
else {
e = (c >> 1);
h = d & 0xf0;
l = d & 0x0f;
while(e--) {
if(hf) {
line[n++] |= (h >> 4);
line[n] = (l <<4);
}
else line[n++] = d;
}
if(c & 0x01) {
if(hf) {
line[n++] |= (h >> 4);
hf = FALSE;
}
else {
line[n] = h;
hf = TRUE;
}
}
}
} while(1);
}
if(compress == BI_RLE8) {
n = 0;
do {
c = fgetc(fp);
d = fgetc(fp);
if(c == 0) {
if(d == 0 || d == 1) break;
if(d > 2) {
while(d--) line[n++] = fgetc(fp);
if(ftell(fp) & 1) fgetc(fp);
}
}
else
while(c--) line[n++] = d;
} while(1);
}
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadCUT(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp, *fpp;
int c, d, i, j, k, l, n = 0;
char *line;
long bufsize, os;
char huge *gptr;
char *ptrpath;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
bmp.biWidth = getw(fp);
bmp.biHeight = getw(fp);
bmp.biBitCount = picbits = 8;
linewidth = SetLine();
memset(palette, 0, 768);
ptrpath = path;
while(*ptrpath) {
if(*ptrpath == '.') {
_fmemcpy(++ptrpath, "pal", 3);
break;
} else ptrpath++;
}
if((fpp = fopen(path, "rb")) != NULL) {
fseek(fpp, 40, SEEK_SET);
c = 472;
for(i = 0; i < 256; ++i) {
for(j = 0; j < 3; ++j)
palette[n++] = getw(fpp) & 0xff;
c -= 6;
if(c < 6) {
fseek(fpp, ftell(fpp) + c, SEEK_SET);
c = 512;
}
}
fclose(fpp);
} else memcpy(palette, "\000\000\000\377\377\377", 6);
if((line = malloc(linewidth)) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
GlobalFree(ghnd);
return(NO_GPTR);
}
fseek(fp, 6, SEEK_SET);
for(j = 0; j < bmp.biHeight; ++j) {
n = 0;
i = getw(fp);
os = ftell(fp);
do {
k = fgetc(fp);
if(k & 0x80) {
l = k & 0x7f;
d = fgetc(fp);
while(l--) line[n++] = d;
}
else {
l = k;
while(l--) line[n++] = fgetc(fp);
}
} while(k != 0 && n < linewidth);
fseek(fp, os + i, SEEK_SET);
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadGIF(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale, long os) {
FILE *fp;
int bits;
int bits2; /* Bits plus 1 */
int codesize; /* Current code size in bits */
int codesize2; /* Next codesize */
int nextcode; /* Next available table entry */
int thiscode; /* Code being expanded */
int oldtoken; /* Last symbol decoded */
int currentcode; /* Code just read */
int oldcode; /* Code read before this one */
int bitsleft; /* Number of bits left in *p */
int blocksize = 0; /* Bytes in next block */
int row = 0; /* next line to write */
int byte = 0; /* next byte to write */
int pass = 0; /* pass number for interlaced pictures */
int u; /* Stack index into firstcodestack */
int p = 0; /* Pointer into current block */
int b, c, i, j, n;
char *line;
static int firstcodestack[4096]; /* Stack for first codes */
static int lastcodestack[4096]; /* Statck for previous code */
static int codestack[4096]; /* Stack for links */
static int wordmasktable[] = {0x0000,0x0001,0x0003,0x0007,
0x000f,0x001f,0x003f,0x007f,
0x00ff,0x01ff,0x03ff,0x07ff,
0x0fff,0x1fff,0x3fff,0x7fff};
static int inctable[] = { 8,8,4,2,0 }; /* interlace increments */
static int startable[] = { 0,4,2,1,0 }; /* interlace starts */
long bufsize;
char huge *gptr;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if(fread((char *)&gif,1,sizeof(GIFHEAD),fp) != sizeof(GIFHEAD) ||
_fmemcmp(gif.sig, "GIF", 3)) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = gif.screenwidth;
bmp.biHeight = gif.screenheight;
bmp.biBitCount = 8;
picbits = (gif.flags & 0x0007) + 1;
linewidth = SetLine();
memset(palette, 0, 768);
if(gif.flags & 0x80) {
c = 3 * (1 << ((gif.flags & 7) + 1));
if(fread(palette, 1, c, fp) != c) {
fclose(fp);
return(BAD_READ);
}
}
while((c = fgetc(fp)) != EOF && (c == ',' || c == '!' || c & 0xff)) {
if (c == ',') {
if(os != 0) fseek(fp, os, SEEK_SET);
if(fread(&iblk,1,sizeof(IMAGEBLOCK),fp) != sizeof(IMAGEBLOCK)) {
fclose(fp);
return(BAD_READ);
}
bmp.biWidth = iblk.width;
bmp.biHeight = iblk.height;
picbits = (iblk.flags & 0x0007) + 1;
linewidth = SetLine();
if(iblk.flags & 0x80) {
memset(palette, 0, 768);
b = 3 * (1 << ((iblk.flags & 0x0007) + 1));
if(fread(palette, 1, b, fp) != b) {
fclose(fp);
return(BAD_READ);
}
}
if((line = malloc(max(linewidth, (short)bmp.biWidth))) == NULL) {
fclose(fp);
return (NO_OPEN);
}
bits = fgetc(fp);
bitsleft = 8;
if(bits < 2 || bits > 8) {
fclose(fp);
free(line);
return(BAD_BIT);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
GlobalFree(ghnd);
return(NO_GPTR);
}
bits2 = 1 << bits;
nextcode = bits2 + 2;
codesize2 = 1 << (codesize = bits + 1);
oldcode = oldtoken = -1;
for(;;) {
if(bitsleft == 8) {
if(++p >= blocksize) {
p = 0;
blocksize = fgetc(fp);
if((blocksize < 1) ||
(fread(buf, 1, blocksize, fp) < blocksize)) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
fclose(fp);
free(line);
return(BAD_READ);
}
}
bitsleft = 0;
}
thiscode = buf[p];
if((currentcode = (codesize + bitsleft)) <= 8) {
buf[p] >>= codesize;
bitsleft = currentcode;
}
else {
if(++p >= blocksize) {
p = 0;
blocksize = fgetc(fp);
if((blocksize < 1) ||
(fread(buf, 1, blocksize, fp) < blocksize)) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_READ);
}
}
thiscode |= buf[p] << (8 - bitsleft);
if(currentcode <= 16) buf[p] >>= (bitsleft = currentcode - 8);
else {
if(++p >= blocksize) {
p = 0;
blocksize = fgetc(fp);
if ((blocksize < 1) ||
(fread(buf, 1, blocksize, fp) < blocksize)) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_READ);
}
}
thiscode |= buf[p] << (16 - bitsleft);
buf[p] >>= (bitsleft = currentcode - 16);
}
}
thiscode &= wordmasktable[codesize];
currentcode = thiscode;
if(thiscode == (bits2 + 1)) break; /* found EOI */
if(thiscode > nextcode) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_CODE);
}
if(thiscode == bits2) {
nextcode = bits2 + 2;
codesize2 = 1 << (codesize = (bits + 1));
oldtoken = oldcode = -1;
continue;
}
u = 0;
if(thiscode == nextcode) {
if(oldcode == -1) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_FIRST);
}
firstcodestack[u++] = oldtoken;
thiscode = oldcode;
}
while(thiscode >= bits2) {
firstcodestack[u++] = lastcodestack[thiscode];
thiscode = codestack[thiscode];
}
oldtoken = thiscode;
do {
line[byte++] = thiscode;
if(byte >= bmp.biWidth) {
if(_fmemcpy(gptr + (bmp.biHeight - row - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
byte = 0;
/* check for interlaced image */
if(iblk.flags & 0x40) {
row += inctable[pass];
if(row >= bmp.biHeight)
row = startable[++pass];
} else ++row;
}
if (u <= 0) break;
thiscode = firstcodestack[--u];
} while(1);
if(nextcode < 4096 && oldcode != -1) {
codestack[nextcode] = oldcode;
lastcodestack[nextcode] = oldtoken;
if (++nextcode >= codesize2 && codesize < 12)
codesize2 = 1 << ++codesize;
}
oldcode = currentcode;
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
else if(c == '!') {
b = fgetc(fp);
switch(b) {
case 0x001:
fseek(fp, 13, SEEK_CUR);
do {
n = 0;
if((n = getc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
} while(n > 0);
break;
case 0x00f9:
fseek(fp, 6, SEEK_CUR);
break;
case 0x00fe:
n = 0;
do {
n = 0;
if((n = fgetc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
} while(n >0);
break;
case 0x00ff:
fseek(fp, 12, SEEK_CUR);
do {
n = 0;
if((n = fgetc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
} while(n >0);
break;
default:
do {
n = 0;
if((n = fgetc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
} while(n >0);
break;
}
}
}
fclose(fp);
return(NO_BMP);
}
HBITMAP FAR PASCAL ReadHRZ(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int i, j, n;
char r, g, b;
char *line;
long bufsize;
char huge *gptr;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
bmp.biWidth = 256;
bmp.biHeight = 240;
bmp.biBitCount = picbits = 24;
linewidth = SetLine();
memset(palette, 0, 768);
if((line = malloc(linewidth)) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = bmp.biHeight * linewidth;
ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
if((gptr = GlobalLock(ghnd)) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
for(j = 0; j != bmp.biHeight - 1; ++j) {
n = 0;
for(i = 0; i < 256; ++i) {
r = fgetc(fp);
g = fgetc(fp);
b = fgetc(fp);
line[n++] = b << 2;
line[n++] = g << 2;
line[n++] = r << 2;
}
if(ferror(fp)) {
free(line);
fclose(fp);
return(BAD_READ);
}
else {
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadIFF(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, k, l, n, t;
unsigned long lng, pos;
char *line, *templine;
char subtype[4];
long bufsize;
char huge *gptr;
int bytes;
lstrcpy(path,fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
fread(buf, 1, 4, fp);
if(!memcmp(buf,"FORM",4) &&
!memcmp(buf,"LIST",4) &&
!memcmp(buf,"CAT ",4)) {
fclose(fp);
return(BAD_HEAD);
}
fread(buf, 1, 8, fp);
_fmemcpy(subtype, buf + 4, 4);
do {
fread(buf, 1, 4, fp);
lng = GetMIlng(fp, FALSE);
if(lng & 1L) ++lng;
pos = ftell(fp);
if(!memcmp(buf, "BMHD", 4)) {
if(fread((char *)&iff, 1, sizeof(IFFHEAD), fp)
!= sizeof(IFFHEAD)) return(BAD_HEAD);
bmp.biWidth = motr2intelint(iff.w, FALSE);
bmp.biHeight = motr2intelint(iff.h, FALSE);
bmp.biBitCount = picbits = iff.nPlanes;
linewidth = SetLine();
if(!_fmemcmp(subtype, "ILBM", 4))
bytes = pixels2bytes(bmp.biWidth) * iff.nPlanes;
else
bytes = bmp.biWidth;
}
if(!memcmp(buf, "CMAP", 4)) {
memset(palette, 0, 768);
if(lng <= 768) {
if(fread(palette, 1, (short)lng, fp) != lng) return(BAD_READ);
}
else {
if(fread(palette, 1, 768, fp) != 768) return(BAD_READ);
fseek(fp, lng - 768L, SEEK_SET);
}
}
if(!memcmp(buf, "BODY", 4)) {
if((line = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
if((templine = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
free(templine);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
free(templine);
GlobalFree(ghnd);
return(NO_GPTR);
}
for(j = 0; j < bmp.biHeight; ++j) {
if(iff.compression) {
n = 0;
do {
c = fgetc(fp);
if(c & 0x80) {
if(c != 0x80) {
i = ((~c) & 0xff) + 2;
c = fgetc(fp);
while(i--) line[n++] = c;
}
}
else {
i = c + 1;
while(i--) line[n++] = fgetc(fp);
}
} while(n < bytes);
}
else
fread(line, 1, bytes, fp);
if(bmp.biBitCount == 4 || bmp.biBitCount == 8) {
t = 0;
n = bytes / iff.nPlanes;
memset(templine, 0, linewidth);
if(bmp.biBitCount <= 4) {
for(i = 0; i < n; ++i) {
for(k = 0; k < 8; k += 2) {
for(l = 0; l < iff.nPlanes; ++l) {
if(line[i + l * n] & masktable[k])
templine[t] |= bittable[l + 4];
if(line[i + l * n] & masktable[k + 1])
templine[t] |= bittable[l];
}
t++;
}
}
}
else {
for(i = 0; i < n; ++i) {
for(k = 0; k < 8; k++) {
for(l = 0; l < iff.nPlanes; ++l)
if(line[i + l * n] & masktable[k])
templine[t] |= bittable[l];
t++;
}
}
}
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, templine, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(templine);
fclose(fp);
return(BAD_COPY);
}
}
else
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(templine);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
free(templine);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
fseek(fp, pos + lng, SEEK_SET);
} while(!feof(fp) || memcmp(buf, "BODY", 4));
return(NO_BMP);
}
HBITMAP FAR PASCAL ReadIMG(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, k, l, n = 0, p = 1, t;
char *line, *templine;
long bufsize;
char huge *gptr;
int bytes;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if((fread((char *)&img, 1, sizeof(IMGHEAD), fp) != sizeof(IMGHEAD)) ||
(memcmp(img.name, "\000U\000U", 4))) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = motr2intelint(img.width, FALSE);
bmp.biHeight = motr2intelint(img.height, FALSE);
bmp.biBitCount = picbits = img.bits;
if(img.flag == 9) bmp.biBitCount = picbits = 24;
if(bmp.biBitCount == 24) bytes = bmp.biWidth * 3;
else bytes = pixels2bytes(bmp.biWidth) * bmp.biBitCount;
linewidth = SetLine();
memset(palette, 0, 768);
if(bmp.biBitCount <= 8) {
if(bmp.biBitCount == 1)
memcpy(palette, "\377\377\377\000\000\000", 6);
else {
n = 255 / ((1 << img.bits) - 1);
for(i = 0; i < (1 << img.bits); ++i)
memset(palette + i * 3, i * n, 3);
}
}
if((line = malloc(max((short)bmp.biWidth, linewidth))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
if((templine = malloc(max((short)bmp.biWidth, linewidth))) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
free(templine);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
free(templine);
GlobalFree(ghnd);
return(NO_GPTR);
}
fseek(fp, 16, SEEK_SET);
if(bmp.biBitCount == 24) {
p = getc(fp);
p = getc(fp);
}
for (j = 0; j < bmp.biHeight; ++j) {
n = 0;
do {
c = fgetc(fp);
if(c & 0x80) {
if(c == 0x80) {
i = fgetc(fp) * p;
while(i--) {
if(n >= bytes) break;
line[n++] = fgetc(fp);
}
}
else {
i = (c & 0x7f) * p;
while(i--) {
if(n >= bytes) break;
line[n++] = 0xff;
}
}
}
else {
if(c == 0) {
i = fgetc(fp) * p;
c = fgetc(fp);
}
else {
i = c * p;
c = 0;
}
while(i--) {
if(n >= bytes) break;
line[n++] = c;
}
}
} while(n < bytes);
if(bmp.biBitCount == 1 || bmp.biBitCount == 24)
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
if(bmp.biBitCount > 1 && bmp.biBitCount <= 8) {
t = 0;
n = bytes / img.bits;
memset(templine, 0, linewidth);
if(bmp.biBitCount <= 4) {
for(i = 0; i < n; ++i)
for(k = 0; k < 8; k += 2) {
for(l = 0; l < img.bits; ++l) {
if(line[i + l * n] & masktable[k])
templine[t] |= bittable[l + 4];
if(line[i + l * n] & masktable[k + 1])
templine[t] |= bittable[l];
}
++t;
}
}
else {
for(i = 0; i < n; ++i)
for(k = 0; k < 8; ++k) {
for(l = 0; l < img.bits; ++l)
if(line[i + l * n] & masktable[k])
templine[t] |= (masktable[l] >> (8 - img.bits));
++t;
}
}
for(i = 0; i < linewidth; ++i)
templine[i] = ~templine[i];
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, templine, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(templine);
fclose(fp);
return(BAD_COPY);
}
}
}
free(line);
free(templine);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadMAC(LPSTR fname, HDC pichdc, HWND pichwnd,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, k, n;
char *line;
long bufsize;
unsigned char huge *gptr;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if(fread((char *)&mac, 1, sizeof(MACHEAD), fp) != sizeof(MACHEAD)) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = 576;
bmp.biHeight = 720;
bmp.biBitCount = picbits = 1;
linewidth = SetLine();
memset(palette, 0, 768);
memcpy(palette, "\377\377\377\000\000\000", 6);
if((line = malloc(72)) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
GlobalFree(ghnd);
return(NO_GPTR);
}
if(!memcmp(mac.type, "PNTG", 4)) fseek(fp, 640, SEEK_SET);
else if(mac.zerobyte == 0) fseek(fp, 512, SEEK_SET);
else fseek(fp, 0, SEEK_SET);
for (j = 0; j < bmp.biHeight; ++j) {
n = 0;
do {
c = fgetc(fp);
if(c & 0x80) {
if(c != 0x80) {
i = ((~c) & 0xff) + 2;
c = fgetc(fp);
while(i--) {
if(n > 72) break;
line[n++] = c;
}
}
}
else {
i = c + 1;
while(i--) {
if(n > 72) break;
line[n++] = fgetc(fp);
}
}
} while(n < 72);
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, 72) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, 0, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadMSP(LPSTR fname, HDC pichdc, HWND pichwnd,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, k, n;
char *line;
long bufsize;
unsigned char huge *gptr;
int bytes;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if(fread((char *)&msp, 1, sizeof(MSPHEAD), fp) != sizeof(MSPHEAD)) {
fclose(fp);
return(BAD_HEAD);
}
if((msp.key1 == 0x6144 || msp.key1 == 0x694c) &&
(msp.key2 == 0x4d6e || msp.key2 == 0x536e)) {
bmp.biWidth = msp.width;
bmp.biHeight = msp.height;
bmp.biBitCount = picbits = 1;
bytes = pixels2bytes(msp.width);
linewidth = SetLine();
}
else {
fclose(fp);
return(BAD_HEAD);
}
memset(palette, 0, 768);
memcpy(palette, "\000\000\000\377\377\377", 6);
if((line = malloc(max(bytes, linewidth))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
GlobalFree(ghnd);
return(NO_GPTR);
}
fseek(fp, bmp.biHeight * 2 + 32, SEEK_SET);
for (j = 0; j < bmp.biHeight; ++j) {
n = 0;
do {
c = fgetc(fp);
if(!c) {
k = fgetc(fp) & 0x00ff;
c = fgetc(fp);
for(i=0; i<k; ++i) line[n++] = c;
}
else {
for(i=0; i<c; ++i) line[n++] = fgetc(fp);
}
} while(n < bytes);
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, 0, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadPCX(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, k, l, n, t;
char *line, *templine;
long bufsize;
char huge *gptr;
int bytes;
char *pal;
static char pcxpalette[48] = {0x00, 0x00, 0x0E, 0x00, 0x52, 0x07, 0x2C, 0x00,
0x0E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x2C, 0x00,
0x85, 0x0F, 0x42, 0x00, 0x00, 0x21, 0x00, 0x00,
0x00, 0x00, 0x6A, 0x24, 0x9B, 0x49, 0xA1, 0x5E,
0x90, 0x5E, 0x18, 0x5E, 0x84, 0x14, 0xD9, 0x95,
0xA0, 0x14, 0x12, 0x00, 0x06, 0x00, 0x68, 0x1F};
lstrcpy(path,fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if((fread((char *)&pcx, 1, sizeof(PCXHEAD), fp) != sizeof(PCXHEAD)) ||
pcx.manufacturer != 0x0a) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = pcx.xmax - pcx.xmin + 1;
bmp.biHeight = pcx.ymax - pcx.ymin + 1;
bytes = pcx.bytes_per_line * pcx.color_planes;
bmp.biBitCount = picbits = pcx.bits * pcx.color_planes;
linewidth = SetLine();
memset(palette, 0, 768);
if(bmp.biBitCount <= 8) {
if(bmp.biBitCount == 1) memcpy(palette, "\000\000\000\377\377\377", 6);
if(bmp.biBitCount == 4) memcpy(palette, pcx.palette, 48);
if(pcx.version == 3) memcpy(palette, pcxpalette, 48);
if(bmp.biBitCount == 8 && pcx.version >= 5) {
fseek(fp, -769L, SEEK_END);
if(fgetc(fp) == 12) {
if(fread(palette, 1, 768, fp) != 768) {
fclose(fp);
return(BAD_READ);
}
}
}
}
if((line = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
if((templine = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
bufsize = max(bytes, linewidth) * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
free(templine);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
free(templine);
GlobalFree(ghnd);
return(NO_GPTR);
}
if(bmp.biBitCount == 24) linewidth = max(bytes, linewidth);
fseek(fp, 128L, SEEK_SET);
for(j = 0; j < bmp.biHeight; ++j) {
n = 0;
do {
c = fgetc(fp);
if((c & 0xc0) == 0xc0) {
i = c & 0x3f;
c = fgetc(fp);
while(i--) {
if(n >= bytes) break;
line[n++]=c;
}
}
else {
if(n >= bytes) break;
line[n++]=c;
}
} while(n < bytes);
if(pcx.color_planes == 1) {
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(templine);
fclose(fp);
return(BAD_COPY);
}
}
if(pcx.color_planes > 1 && pcx.color_planes <= 4) {
t = 0;
n = bytes / pcx.color_planes;
if(bmp.biBitCount == 24) {
for(i = 0; i < n; ++i)
for(k = 2; k > -1; k--) templine[t++] = line[i + n * k];
}
else {
memset(templine, 0, linewidth);
for(i = 0; i < n; ++i) {
for(k = 0; k < 8; k += 2) {
for(l = 0; l < pcx.color_planes; ++l) {
if(line[i + l * n] & masktable[k])
templine[t] |= bittable[l + 4];
if(line[i + l * n] & masktable[k + 1])
templine[t] |= bittable[l];
}
t++;
}
}
}
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, templine, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(templine);
fclose(fp);
return(BAD_COPY);
}
}
}
free(line);
free(templine);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadPIC(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
unsigned long l;
int bcount, c, i, j, k, n, ldex = 0, len, t = 0;
int r, b, g;
int row = 0;
int pass, pos;
char *line, *block;
char bits;
char temppal[48];
long bufsize;
char huge *gptr;
int bytes;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if((fread((char *)&pic, 1, sizeof(PICHEAD), fp) != sizeof(PICHEAD)) ||
(pic.mark != 0x1234)) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = pic.xsize;
bmp.biHeight = pic.ysize;
n = (pic.bitsinf & 0xf0) / 16 + 1;
bits = picbits = bmp.biBitCount = n * (pic.bitsinf & 0xf);
if(bmp.biBitCount == 8) bytes = pic.xsize;
else bytes = pixels2bytes(pic.xsize);
linewidth = SetLine();
memset(palette, 0, 768);
fread(palette, 1 , pic.esize, fp);
if(bits == 1)
memcpy(palette, "\000\000\000\377\377\377", 6);
else if(bits > 1 && bits <= 4 && pic.evideo != 'M') {
for(i = 0; i < (1 << bits); ++i) {
r = g = b = 0;
if(palette[i] & 0x01) b += 0x80;
if(palette[i] & 0x08) b += 0x40;
if(palette[i] & 0x02) g += 0x80;
if(palette[i] & 0x10) g += 0x40;
if(palette[i] & 0x04) r += 0x80;
if(palette[i] & 0x20) r += 0x40;
temppal[t++] = r;
temppal[t++] = g;
temppal[t++] = b;
}
_fmemcpy(palette, temppal, (1 << bits) * 3);
} else
for(i = 0; i < pic.esize; ++i)
palette[i] <<= 2;
if((line = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
if((block = malloc(8192)) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
bufsize = linewidth * bmp.biHeight;
if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
fclose(fp);
free(line);
free(block);
return(MEM_ERR);
}
if((gptr = GlobalLock(ghnd)) == NULL) {
fclose(fp);
free(line);
free(block);
GlobalFree(ghnd);
return(NO_GPTR);
}
if(bits > 1 && bits <= 4) {
_fmemset(gptr, 0, (unsigned)bufsize);
row = bmp.biHeight * bits;
} else
row = bmp.biHeight;
bcount = getw(fp);
if(bcount) {
for(i = 0; i < bcount; ++i) {
l = ftell(fp);
pos = 0;
if(fread((char *)&pbk, 1, sizeof(PICBLOCK), fp) != sizeof(PICBLOCK)) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(block);
fclose(fp);
return(BAD_READ);
}
do {
c = fgetc(fp);
len = 1;
if(c == pbk.mbyte) {
len = fgetc(fp);
if(len == 0) len = getw(fp);
c = fgetc(fp);
memset(block + ldex, c, len);
ldex += len;
} else block[ldex++] = c;
pos += len;
while(ldex >= bytes) {
ldex -= bytes;
if(bmp.biBitCount == 8 || bmp.biBitCount == 1)
if (row > 0)
if(_fmemcpy(gptr + (bmp.biHeight - row) * linewidth, block, bytes) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(block);
fclose(fp);
return(BAD_COPY);
}
if(bits >1 && bits <= 4) {
if(_fmemcpy(line, gptr + (bmp.biHeight - row % bmp.biHeight - 1) * linewidth, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(block);
fclose(fp);
return(BAD_COPY);
}
pass = row / bmp.biHeight;
n = 0;
for(j = 0; j < bytes; ++j) {
for(k = 0; k < 8; k += 2) {
if(block[j] & masktable[k]) line[n] |= bittable[7 - pass];
if(block[j] & masktable[k + 1]) line[n] |= bittable[3 - pass];
n++;
}
}
if(_fmemcpy(gptr + (bmp.biHeight - row % bmp.biHeight - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
free(block);
fclose(fp);
return(BAD_COPY);
}
}
--row;
memmove(block, block + bytes, ldex);
}
} while(pos < pbk.bsize && c != EOF);
fseek(fp, l + (long)pbk.pbsize, SEEK_SET);
}
}
else {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(block);
free(line);
fclose(fp);
return(BAD_READ);
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadRAS(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, n, m;
long bits, typ, mtyp, mapl, pl;
char *line;
long bufsize;
char huge *gptr;
int bytes;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if(GetMIlng(fp, FALSE) != 0x59a66a95) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = GetMIlng(fp, FALSE);
bmp.biHeight = GetMIlng(fp, FALSE);
bits = bmp.biBitCount = picbits = GetMIlng(fp, FALSE);
bytes = linewidth = SetLine();
memset(palette, 0, 768);
GetMIlng(fp, FALSE);
typ = GetMIlng(fp, FALSE);
if(typ == 0xffff) {
fclose(fp);
return(BAD_HEAD);
}
mtyp = GetMIlng(fp, FALSE);
if(mtyp == 0x2) {
fclose(fp);
return(BAD_HEAD);
}
mapl = GetMIlng(fp, FALSE);
if(bmp.biBitCount == 1) memcpy(palette,"\000\000\000\377\377\377",6);
if(mtyp) {
fread(tmppalette, 1, (int)mapl, fp);
pl = mapl / 3;
j = 0;
for(i = 0; i < pl; ++i) {
if(i >= 256) break;
palette[i * 3] = tmppalette[j++];
palette[i * 3 + 1] = tmppalette[i + pl];
palette[i * 3 + 2] = tmppalette[i + pl * 2];
}
}
if((line = malloc(max(linewidth, bytes))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = bmp.biHeight * linewidth;
ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
if((gptr = GlobalLock(ghnd)) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
if(bmp.biBitCount == 24) {
bytes = bmp.biWidth * 3;
while(bytes & 0x0001) ++bytes;
}
for(j = 0; j != bmp.biHeight - 1; ++j) {
n = 0;
/* handle uncompressed lines */
if(typ != 0x02) {
if(bits == 1 || bits == 8 || bits == 24) {
fread(line, 1, bytes, fp);
n = bytes;
}
if(bits == 32) {
for(i = 0; i < bmp.biWidth; ++i) {
if(n >= bytes - 3) continue;
fgetc(fp);
line[n++] = fgetc(fp);
line[n++] = fgetc(fp);
line[n++] = fgetc(fp);
}
}
}
/* handle compressed lines */
else {
do {
c = fgetc(fp);
if(c != 0x80) line[n++] = c;
else {
c = fgetc(fp);
if(c == 0) line[n++] = 0x80;
else {
m = fgetc(fp);
for(i = 0; i < c; ++i) if(n <= bytes) line[n++] = m;
}
}
} while(n < bytes);
}
if(ferror(fp)) {
free(line);
fclose(fp);
return(BAD_READ);
}
else {
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadTGA(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, n, m, size;
int r, g, b;
int startline, endline, incline;
char *line, *templine;
long bufsize;
char huge *gptr;
int bytes;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if((fread((char *)&tga, 1, sizeof(TGAHEAD), fp) != sizeof(TGAHEAD)) ||
(tga.imagetype != 0x01 &&
tga.imagetype != 0x02 &&
tga.imagetype != 0x03 &&
tga.imagetype != 0x09 &&
tga.imagetype != 0x0a &&
tga.imagetype != 0x0b)) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biWidth = tga.width;
bmp.biHeight = tga.depth;
bmp.biBitCount = picbits = tga.bits;
if(bmp.biBitCount == 1) bytes = pixels2bytes(bmp.biWidth);
else if(bmp.biBitCount == 8) bytes = bmp.biWidth;
else bytes = bmp.biWidth * 3;
linewidth = SetLine();
memset(palette, 0, 768);
fseek(fp, (long)tga.identsize, SEEK_CUR);
if(tga.bits == 1) memcpy(palette,"\000\000\000\377\377\377",6);
if(tga.colormaptype) {
switch(tga.colormapbits) {
case 24:
for(i = tga.colormapstart; i < tga.colormaplength; ++i) {
if(i >= 256) break;
palette[i * 3 + 2] = fgetc(fp);
palette[i * 3 + 1] = fgetc(fp);
palette[i * 3] = fgetc(fp);
}
break;
case 16:
for(i = tga.colormapstart; i < tga.colormaplength; ++i) {
if(i >= 256) break;
n = getw(fp);
palette[i * 3 + 2] = ((n >> 10) & 0x1f) << 3;
palette[i * 3 + 1] = ((n >> 5) & 0x1f) << 3;
palette[i * 3] = (n & 0x1f) << 3;
}
break;
}
}
else
if(tga.bits == 8)
for(i = 0; i < 256; ++i)
memset(palette + i * 3, i, 3);
if((line = malloc(max(bytes, linewidth))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = bmp.biHeight * linewidth;
ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
if((gptr = GlobalLock(ghnd)) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
if(tga.descriptor & 0x20) {
startline = 0;
endline = bmp.biHeight;
incline = 1;
}
else {
startline = bmp.biHeight - 1;
endline = -1;
incline = -1;
}
for(j = startline; j != endline; j += incline) {
n = m = 0;
/* handle uncompressed lines */
if(tga.imagetype == 0x01 ||
tga.imagetype == 0x02 ||
tga.imagetype == 0x03) {
if(tga.bits == 1 || tga.bits == 8 || tga.bits == 24) {
fread(line, 1, bytes, fp);
n = bytes;
}
if(tga.bits == 16) {
for(i = 0; i < bmp.biWidth; ++i) {
c = getw(fp);
if(n >= bytes - 3) continue;
line[n++] = (c & 0x1f) << 3;
line[n++] = ((c >> 5) & 0x1f) << 3;
line[n++] = ((c >> 10) & 0x1f) << 3;
}
}
if(tga.bits == 32) {
for(i = 0; i < bmp.biWidth; ++i) {
if(n >= bytes - 3) continue;
line[n++] = fgetc(fp);
line[n++] = fgetc(fp);
line[n++] = fgetc(fp);
fgetc(fp);
}
}
}
/* handle compressed lines */
else {
do {
c = fgetc(fp);
size = (c & 0x7f) + 1;
n += size;
if(c & 0x80) {
switch(tga.bits) {
case 1:
case 8:
c = fgetc(fp);
for(i = 0 ; i < size; ++i) {
if(m >= bytes) continue;
line[m++] = c;
}
break;
case 16:
c = getw(fp);
r = ((c >> 10) & 0x1f) << 3;
g = ((c >> 5) & 0x1f) << 3;
b = (c & 0x1f) << 3;
for(i = 0; i < size; ++i) {
if(m >= bytes - 3) continue;
line[m++] = b;
line[m++] = g;
line[m++] = r;
}
break;
case 24:
b = fgetc(fp);
g = fgetc(fp);
r = fgetc(fp);
for(i = 0; i < size; ++i) {
if(m >= bytes - 3) continue;
line[m++] = b;
line[m++] = g;
line[m++] = r;
}
break;
case 32:
b = fgetc(fp);
g = fgetc(fp);
r = fgetc(fp);
fgetc(fp);
for(i = 0; i < size; ++i) {
if(m >= bytes - 3) continue;
line[m++] = b;
line[m++] = g;
line[m++] = r;
}
break;
}
}
else {
switch(tga.bits) {
case 1:
case 8:
for(i = 0; i < size; ++i) {
if(m >= bytes) continue;
line[m++] = fgetc(fp);
}
break;
case 16:
for(i = 0; i < size; ++i) {
c = getw(fp);
r = ((c >> 10) & 0x1f) << 3;
g = ((c >> 5) & 0x1f) << 3;
b = (c & 0x1f) << 3;
if(m >= bytes - 3) continue;
line[m++] = b;
line[m++] = g;
line[m++] = r;
}
break;
case 24:
for(i = 0; i < size; ++i) {
if(m >= bytes - 3) continue;
line[m++] = fgetc(fp);
line[m++] = fgetc(fp);
line[m++] = fgetc(fp);
}
break;
case 32:
for(i = 0; i < size; ++i) {
if(m >= bytes - 3) continue;
line[m++] = fgetc(fp);
line[m++] = fgetc(fp);
line[m++] = fgetc(fp);
fgetc(fp);
}
break;
}
}
} while(n < bytes);
}
if(ferror(fp)) {
free(line);
fclose(fp);
return(BAD_READ);
}
else {
if(tga.descriptor & 0x10) {
if((templine = malloc(bytes)) != NULL) {
for(i = 0; i < bytes; ++i)
templine[i] = line[bytes - 1 - i];
memcpy(line, templine, bytes);
free(templine);
}
}
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, bytes) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadTIF(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, i, j, k, n, row = 0, t;
int colormap = FALSE, motint = FALSE;
char *line;
long bufsize;
unsigned long length, offset, pos, strtstrip;
unsigned int numtags, photo = 0, rows = 0, numstrips = 1, compress = 1;
unsigned int bitsamples = 1, bitspersample = 1, tag, type;
char huge *gptr;
int bytes;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
fread(buf, 1, 2, fp);
if(!_fmemcmp(buf, "II", 2) && !_fmemcmp(buf, "MM", 2)) {
fclose(fp);
return(BAD_HEAD);
}
if(_fmemcmp(buf, "II", 2) == 0) motint = TRUE;
memset(palette, 0, 768);
getw(fp);
offset = GetMIlng(fp, motint);
fseek(fp, offset, SEEK_SET);
numtags = GetMIw(fp, motint);
for(t = 0; t < numtags; ++t) {
tag = GetMIw(fp, motint);
type = GetMIw(fp, motint);
if(type == 4) {
length = GetMIlng(fp, motint);
offset = GetMIlng(fp, motint);
}
else {
if(motint) {
length = GetMIw(fp, motint);
GetMIw(fp, motint);
offset = GetMIw(fp, motint);
GetMIw(fp, motint);
}
else {
GetMIw(fp, motint);
length = GetMIw(fp, motint);
if(length > 2L) {
GetMIw(fp, motint);
offset = GetMIw(fp, motint);
}
else {
offset = GetMIw(fp, motint);
GetMIw(fp, motint);
}
}
}
pos = ftell(fp);
switch(tag) {
case 256:
bmp.biWidth = offset;
break;
case 257:
bmp.biHeight = offset;
break;
case 258:
if(length > 1L) {
pos = ftell(fp);
fseek(fp, offset, SEEK_SET);
bitspersample = GetMIw(fp, motint);
fseek(fp, pos, SEEK_SET);
} else bitspersample = offset;
break;
case 259:
compress = offset;
break;
case 262:
photo = offset;
break;
case 273:
if(type == 4) strtstrip = offset;
else strtstrip = offset & 0xffffL;
numstrips = length;
break;
case 277:
bitsamples = offset;
break;
case 278:
rows = offset;
break;
case 320:
pos = ftell(fp);
colormap = TRUE;
fseek(fp, offset, SEEK_SET);
for(i = 0; i < (1 << bitspersample); ++i) {
if(i >= 256) break;
c = GetMIw(fp, motint);
if((c & 0xff00) && !(c & 0x00ff)) c = c>> 8;
palette[i * 3] = c;
}
for(i = 0; i < (1 << bitspersample); ++i) {
if(i >= 256) break;
c = GetMIw(fp, motint);
if((c & 0xff00) && !(c & 0x00ff)) c = c>> 8;
palette[i * 3 + 1] = c;
}
for(i = 0; i < (1 << bitspersample); ++i) {
if(i >= 256) break;
c = GetMIw(fp, motint);
if((c & 0xff00) && !(c & 0x00ff)) c = c>> 8;
palette[i * 3 + 2] = c;
}
fseek(fp, pos, SEEK_SET);
break;
}
}
bmp.biBitCount = picbits = bitspersample * bitsamples;
bytes = (bmp.biWidth * bmp.biBitCount + 7) >> 3;
linewidth = SetLine();
if(colormap != TRUE) {
if(bmp.biBitCount == 1) {
if(photo != 1)
memcpy(palette, "\377\377\377\000\000\000", 6);
else
memcpy(palette, "\000\000\000\377\377\377", 6);
}
else {
n = 255 / ((1 << bmp.biBitCount) - 1);
for(i = 0; i < (1 << bmp.biBitCount); ++i)
memset(palette + i * 3, i * n, 3);
}
}
if((line = malloc(max(bytes, linewidth))) == NULL) {
fclose(fp);
return(MEM_ERR);
}
bufsize = bmp.biHeight * linewidth;
ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
if((gptr = GlobalLock(ghnd)) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
if(rows == 0) rows = bmp.biHeight;
for(j = 0; j < numstrips; ++j) {
fseek(fp, strtstrip + (j * 4), SEEK_SET);
if(numstrips > 1) fseek(fp, GetMIlng(fp, motint), SEEK_SET);
for(k = 0; k < rows; ++k) {
++row;
if(compress == 1)
fread(line, 1, bytes, fp);
if(compress == 0x8005) {
n = 0;
do {
c = fgetc(fp);
if(c & 0x80) {
if(c != 0x80) {
i = ((~c) & 0xff) + 2;
c = fgetc(fp);
while((i--) && (n < bytes)) line[n++] = c;
}
}
else {
i = (c & 0xff) + 1;
while((i--) && (n < bytes)) line[n++] = fgetc(fp);
}
} while(n < bytes);
}
if(row > bmp.biHeight) continue;
if(compress == 1 || compress == 0x8005) {
if(bmp.biBitCount == 24)
for(i = 0; i < bytes - 3; i += 3) {
c = line[i];
line[i] = line[i + 2];
line[i + 2] = c;
}
if(_fmemcpy(gptr + (bmp.biHeight - row) * linewidth, line, bytes) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
HBITMAP FAR PASCAL ReadWPG(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
WORD print, WORD x, WORD y, WORD scale) {
FILE *fp;
int c, d, i, j, n, type;
unsigned int r;
int repeat = 0;
char *line;
long bufsize;
char huge *gptr;
int bytes;
unsigned long fc, l, t, offset;
lstrcpy(path, fname);
if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
if((fread((char *)&wpg, 1, sizeof(WPGHEAD), fp) != sizeof(WPGHEAD)) ||
(memcmp(wpg.id, "\377WPC", 4))) {
fclose(fp);
return(BAD_HEAD);
}
bmp.biHeight = bmp.biWidth = 0;
fseek(fp, wpg.start, SEEK_SET);
memset(palette, 0, 768);
memcpy(palette,"\000\000\000\377\377\377",6);
do {
type = fgetc(fp);
t = ftell(fp);
r = fgetc(fp);
if(r == 0xff) {
r = getw(fp);
if(r & 0x8000) {
l = (unsigned long)(r & 0x7fff) << 16;
r = getw(fp);
l += (((unsigned long)r) + 4L);
} else l = (((unsigned int)r) + 2L);
} else l = (unsigned long)r;
switch(type) {
case 11:
bmp.biWidth = getw(fp);
bmp.biHeight = getw(fp);
bmp.biBitCount = picbits = getw(fp);
getw(fp);
getw(fp);
offset = ftell(fp);
if(bmp.biBitCount == 1) bytes = pixels2bytes(bmp.biWidth);
else if(bmp.biBitCount > 1 && bmp.biBitCount <= 4) {
j = bmp.biWidth;
if(j & 0x001) ++i;
bytes = (j * 4) >> 3;
}
else bytes = bmp.biWidth;
linewidth = SetLine();
break;
case 14:
fc = getw(fp);
j = getw(fp);
for(i = 0; i < j; ++i) {
if((fc + i * 3) >= 768) break;
palette[(fc + i) * 3] = fgetc(fp);
palette[((fc + i) * 3) + 1] = fgetc(fp);
palette[((fc + i) * 3) + 2] = fgetc(fp);
}
break;
case 16:
if(bmp.biWidth = 0 || bmp.biHeight == 0) {
fclose(fp);
return (NO_BMP);
}
fseek(fp, offset, SEEK_SET);
if((line = malloc(max(bytes, (short)bmp.biWidth))) == NULL) {
fclose(fp);
return (MEM_ERR);
}
bufsize = bmp.biHeight * linewidth;
ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
if((gptr = GlobalLock(ghnd)) == NULL) {
free(line);
fclose(fp);
return(MEM_ERR);
}
for (j = 0; j < bmp.biHeight; ++j) {
n = 0;
if(repeat) --repeat;
else {
do {
c = fgetc(fp);
if((c & 0x0080) && (c & 0x007f)) {
d = fgetc(fp);
for(i = 0; i < (c & 0x7f); ++i) line[n++] = d;
}
else if((c & 0x0080) && !(c & 0x007f)) {
d = fgetc(fp);
for(i = 0; i < d; ++i) line[n++] = 0xff;
}
else if(!(c & 0x0080) && (c & 0x007f)) {
for(i = 0; i < (c & 0x7f); ++i) line[n++] = fgetc(fp);
}
else {
repeat = fgetc(fp);
n = bytes;
}
} while(n < bytes);
}
if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, bytes) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
free(line);
fclose(fp);
return(BAD_COPY);
}
}
free(line);
fclose(fp);
return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
}
fseek(fp, t + l + 1, SEEK_SET);
} while(r != 16 && r != EOF);
return(NO_BMP);
}
int SetLine() {
int j, width;
bmp.biSize = 40;
bmp.biPlanes = 1;
bmp.biCompression = 0;
bmp.biSizeImage = 0;
bmp.biXPelsPerMeter = 0;
bmp.biYPelsPerMeter = 0;
bmp.biClrUsed = 0;
bmp.biClrImportant = 0;
for(j = 0; j < 256; ++j) {
bmpi.bmiColors[j].rgbRed = 0;
bmpi.bmiColors[j].rgbGreen = 0;
bmpi.bmiColors[j].rgbBlue = 0;
bmpi.bmiColors[j].rgbReserved = 0;
}
if(bmp.biBitCount == 1)
width = pixels2bytes(bmp.biWidth);
if(bmp.biBitCount > 1 && bmp.biBitCount <= 4) {
width = pixels2bytes(bmp.biWidth) << 2;
bmp.biBitCount = 4;
}
if(bmp.biBitCount > 4 && bmp.biBitCount <= 8) {
width = bmp.biWidth;
bmp.biBitCount = 8;
}
if(bmp.biBitCount > 8) {
width = bmp.biWidth * 3;
bmp.biBitCount = 24;
}
if(width & 0x003) width = (width | 3) + 1;
bmpi.bmiHeader = bmp;
return(width);
}
int Display(unsigned char huge *gptr, HDC pichdc, HWND pichwnd, int dither,
int print, int x, int y, int scale) {
int bits, j, r;
HDC tempdc;
HANDLE hdcprev, chndl;
HBITMAP bhnd;
LOGPALETTE *plogpal;
HANDLE hpal = NULL, chpal = NULL;
HDC oldpal;
bits = (GetDeviceCaps(pichdc, PLANES) * GetDeviceCaps(pichdc, BITSPIXEL));
if(bits >= 16) bits = 24;
if(bmp.biBitCount > 8 && bits <= 8) {
j = (1 << bits);
if(Quantize(gptr, &j, palette) != 0) return(NO_PAL);
}
if(dither != 0 && picbits != 1) {
if(dither == 1 || picbits > bits) {
r = DitherPicture(gptr);
GlobalUnlock(ghnd);
GlobalFree(ghnd);
if(r != 0) return(r);
ghnd = dh;
gptr = GlobalLock(ghnd);
}
}
if(bmp.biBitCount <= 8 || bits <= 8) {
if(bmp.biBitCount <= 8) j = 1 << bmp.biBitCount;
if((plogpal = (LOGPALETTE *)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + (j * sizeof(PALETTEENTRY)))) != NULL) {
plogpal->palVersion = 0x300;
plogpal->palNumEntries = j;
for(j = 0; j < plogpal->palNumEntries; ++j) {
plogpal->palPalEntry[j].peRed = bmpi.bmiColors[j].rgbRed = palette[j * 3];
plogpal->palPalEntry[j].peGreen = bmpi.bmiColors[j].rgbGreen = palette[j * 3 + 1];
plogpal->palPalEntry[j].peBlue = bmpi.bmiColors[j].rgbBlue = palette[j * 3 + 2];
plogpal->palPalEntry[j].peFlags = bmpi.bmiColors[j].rgbReserved = 0;
}
if((hpal = CreatePalette(plogpal)) == NULL) {
LocalFree((HANDLE)plogpal);
GlobalUnlock(ghnd);
GlobalFree(ghnd);
return(NO_PAL);
}
OpenClipboard(pichwnd);
SetClipboardData(CF_PALETTE, CreatePalette(plogpal));
CloseClipboard();
LocalFree((HANDLE)plogpal);
if((oldpal = SelectPalette(pichdc, hpal, 0)) == NULL) {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
return(NO_PAL);
}
RealizePalette(pichdc);
}
else {
GlobalUnlock(ghnd);
GlobalFree(ghnd);
return(MEM_ERR);
}
}
if(print) {
StretchDIBits(pichdc, x, y,
(short)bmp.biWidth * scale,
(short)bmp.biHeight * scale,
0, 0,
(short)bmp.biWidth, (short)bmp.biHeight,
gptr, (LPBITMAPINFO)&bmpi,
DIB_RGB_COLORS, SRCCOPY);
bhnd = NULL;
}
else {
if(pichwnd != 0) MoveWindow(pichwnd, 0, 0, (short)bmp.biWidth, (short)bmp.biHeight, TRUE);
if((bhnd = CreateDIBitmap(pichdc, (LPBITMAPINFOHEADER)&bmp,
CBM_INIT, gptr, (LPBITMAPINFO)&bmpi,
DIB_RGB_COLORS)) == NULL) bhnd = NO_BHND;
}
if(hpal != NULL) {
SelectPalette(pichdc, oldpal, 0);
DeleteObject(hpal);
}
GlobalUnlock(ghnd);
GlobalFree(ghnd);
return(bhnd);
}
int Quantize(unsigned char huge *gptr, int far *colorcount, char *outputcolormap) {
char far *p, far *linebuffer;
unsigned int i, j;
int index;
int newcolormapsize;
int numofentries;
unsigned long mems;
long cred, cgreen, cblue;
char huge *lpstr;
NEWCOLOR far *newcolorsubdiv;
QCOLOR far *colorarrayentries, far *quantizedcolor;
HANDLE memh;
mems = ((long)sizeof(QCOLOR) * 4096L) +
((long)sizeof(NEWCOLOR) * 256L) +
((long)linewidth) +
((long)sizeof(QCOLOR far *) * 4096L);
if((memh = GlobalAlloc(GMEM_MOVEABLE, mems)) == NULL)
return(MEM_ERR);
if((lpstr = (char huge *)GlobalLock(memh)) == NULL) {
GlobalFree(memh);
return(MEM_ERR);
}
colorarrayentries = (QCOLOR far *)lpstr;
newcolorsubdiv = (NEWCOLOR far *)(lpstr + (long)sizeof(QCOLOR) * 4096L);
linebuffer = (char far *)(lpstr + (((long)sizeof(QCOLOR) * 4096L) +
((long)sizeof(NEWCOLOR) * 256L)));
for(i = 0; i < 4096; i++) {
colorarrayentries[i].RGB[0] = i >> 8;
colorarrayentries[i].RGB[1] = (i >> 4) & 0x0f;
colorarrayentries[i].RGB[2] = i & 0x0f;
colorarrayentries[i].count = 0L;
}
for(i = 0; i < bmp.biHeight; ++i) {
if(_fmemcpy(linebuffer, gptr + (bmp.biHeight - i - 1) * linewidth, linewidth) == NULL) {
GlobalUnlock(memh);
GlobalFree(memh);
return(BAD_COPY);
}
p = linebuffer;
for(j = 0; j < bmp.biWidth; ++j) {
index = ((p[2] & 0xf0) << 4) +
(p[1] & 0xf0) +
((p[0] & 0xf0) >> 4);
colorarrayentries[index].count++;
p += 3;
}
}
for(i = 0; i < 256; i++) {
newcolorsubdiv[i].quantizedcolors = (QCOLOR far *)NULL;
newcolorsubdiv[i].count = 0L;
newcolorsubdiv[i].numentries = 0L;
for(j = 0; j < 3; ++j) {
newcolorsubdiv[i].RGBmin[j] = 0;
newcolorsubdiv[i].RGBwidth[j] = 255;
}
}
for(i = 0; i < 4096; i++)
if(colorarrayentries[i].count > 0) break;
quantizedcolor = newcolorsubdiv[0].quantizedcolors = &colorarrayentries[i];
numofentries = 1;
while(++i < 4096)
if(colorarrayentries[i].count > 0) {
quantizedcolor->pnext = &colorarrayentries[i];
quantizedcolor = &colorarrayentries[i];
numofentries++;
}
quantizedcolor->pnext = (QCOLOR far *)NULL;
newcolorsubdiv[0].numentries = numofentries;
newcolorsubdiv[0].count = (long)bmp.biWidth * (long)bmp.biHeight;
newcolormapsize = 1;
lpstr += ((long)sizeof(QCOLOR) * 4096L) +
((long)sizeof(NEWCOLOR) * 256L) +
((long)linewidth);
DivideMap(newcolorsubdiv, *colorcount, &newcolormapsize, lpstr);
if(newcolormapsize < *colorcount) {
for(i = newcolormapsize; i < *colorcount; i++)
outputcolormap[i * 3] =
outputcolormap[i * 3 + 1] =
outputcolormap[i * 3 + 2] = 0;
}
for(i = 0; i < newcolormapsize; i++) {
if((j = newcolorsubdiv[i].numentries) > 0) {
quantizedcolor = newcolorsubdiv[i].quantizedcolors;
cred = cgreen = cblue = 0;
while(quantizedcolor) {
quantizedcolor->newcolorindex = i;
cred += quantizedcolor->RGB[0];
cgreen += quantizedcolor->RGB[1];
cblue += quantizedcolor->RGB[2];\
quantizedcolor = quantizedcolor->pnext;
}
outputcolormap[i * 3] = (int)(cred << 4) / j;
outputcolormap[i * 3 + 1] = (int)(cgreen << 4) / j;
outputcolormap[i * 3 + 2] = (int)(cblue << 4) / j;
}
}
GlobalUnlock(memh);
GlobalFree(memh);
*colorcount = newcolormapsize;
return(0);
}
int DivideMap(NEWCOLOR far *newcolorsubdiv, int colormapsize,
int far *newcolormapsize, char huge *lpstr) {
unsigned int i, j;
int maxsize, index = 0;
unsigned int numentries, mincolor, maxcolor;
long sum, count;
QCOLOR far *quantizedcolor, far * far *sortarray;
while(colormapsize > *newcolormapsize) {
maxsize = -1;
for(i = 0; i < *newcolormapsize; i++) {
for(j = 0; j < 3; j++) {
if(((int)newcolorsubdiv[i].RGBwidth[j]) > maxsize && newcolorsubdiv[i].numentries > 1) {
maxsize = newcolorsubdiv[i].RGBwidth[j];
index = i;
sortRGBaxis = j;
}
}
}
if(maxsize == -1) return(1);
sortarray = (QCOLOR far * far *)lpstr;
for(j = 0, quantizedcolor = newcolorsubdiv[index].quantizedcolors;
j < newcolorsubdiv[index].numentries && quantizedcolor != (QCOLOR far *)NULL;
j++, quantizedcolor = quantizedcolor->pnext)
sortarray[j] = quantizedcolor;
psort((char far * far *)sortarray, newcolorsubdiv[index].numentries);
for(j = 0; j < newcolorsubdiv[index].numentries - 1; j++)
sortarray[j]->pnext = sortarray[j + 1];
sortarray[newcolorsubdiv[index].numentries - 1]->pnext = (QCOLOR far *)NULL;
newcolorsubdiv[index].quantizedcolors = quantizedcolor = sortarray[0];
sum = newcolorsubdiv[index].count / 2 - quantizedcolor->count;
numentries = 1;
count = quantizedcolor->count;
while((sum -= quantizedcolor->pnext->count) >= 0 &&
quantizedcolor->pnext != (QCOLOR far *)NULL &&
quantizedcolor->pnext->pnext != (QCOLOR far *)NULL) {
quantizedcolor = quantizedcolor->pnext;
numentries++;
count += quantizedcolor->count;
}
maxcolor = quantizedcolor->RGB[sortRGBaxis];
mincolor = quantizedcolor->pnext->RGB[sortRGBaxis];
maxcolor <<= 4;
mincolor <<= 4;
newcolorsubdiv[*newcolormapsize].quantizedcolors = quantizedcolor->pnext;
quantizedcolor->pnext = (QCOLOR far *)NULL;
newcolorsubdiv[*newcolormapsize].count = count;
newcolorsubdiv[index].count -= count;
newcolorsubdiv[*newcolormapsize].numentries = newcolorsubdiv[index].numentries - numentries;
newcolorsubdiv[index].numentries = numentries;
for(j = 0; j < 3; j++) {
newcolorsubdiv[*newcolormapsize].RGBmin[j] = newcolorsubdiv[index].RGBmin[j];
newcolorsubdiv[*newcolormapsize].RGBwidth[j] = newcolorsubdiv[index].RGBwidth[j];
}
newcolorsubdiv[*newcolormapsize].RGBwidth[sortRGBaxis] =
newcolorsubdiv[*newcolormapsize].RGBmin[sortRGBaxis] +
newcolorsubdiv[*newcolormapsize].RGBwidth[sortRGBaxis] -
mincolor;
newcolorsubdiv[*newcolormapsize].RGBmin[sortRGBaxis] = mincolor;
newcolorsubdiv[index].RGBwidth[sortRGBaxis] =
maxcolor - newcolorsubdiv[index].RGBmin[sortRGBaxis];
(*newcolormapsize)++;
}
return(1);
}
void psort(char far * far *array, int number) {
QCOLOR far *q1, far *q2;
int i, j, n, nr;
char far *temp, far *part;
if(number < 8) {
pinsert(array, number);
return;
}
part = array[number / 2];
i = -1;
j = number;
for(;;) {
do {
++i;
q1 = (QCOLOR far *)array[i];
q2 = (QCOLOR far *)part;
n = q1->RGB[sortRGBaxis] - q2->RGB[sortRGBaxis];
} while(n < 0);
do {
--j;
q1 = (QCOLOR far *)array[j];
q2 = (QCOLOR far *)part;
n = q1->RGB[sortRGBaxis] - q2->RGB[sortRGBaxis];
} while(n > 0);
if(i >= j) break;
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
nr = number - i;
if(i < (number / 2)) {
psort(array, i);
psort(&array[i], nr);
}
else {
psort(&array[i], nr);
psort(array, i);
}
}
void pinsert(char far * far *array, int number) {
QCOLOR far *q1, far *q2;
char far *temp, far *part;
int i, j;
for(i = 1; i < number; ++i) {
temp = array[i];
j = i - 1;
while(j >= 0) {
q1 = (QCOLOR far*)temp;
q2 = (QCOLOR far*)array[j];
if(q1->RGB[sortRGBaxis] - q2->RGB[sortRGBaxis] > 0) break;
array[j + 1] = array[j];
--j;
}
array[j + 1] = temp;
}
}
int DitherPicture(unsigned char huge *gptr) {
static char fixedpalette[] = {
0, 0, 0,
255, 0, 0,
0, 255, 0,
255, 255, 0,
0, 0, 255,
255, 0, 255,
0, 255, 255,
255, 255, 255};
static char bayerpattern[8][8] = {
0, 32, 8, 40, 2, 34, 10, 42,
48, 16, 56, 24, 50, 18, 58, 26,
12, 44, 4, 36, 14, 46, 6, 38,
60, 28, 52, 20, 62, 30, 54, 22,
3, 35, 11, 43, 1, 33, 9, 41,
51, 19, 59, 27, 49, 17, 57, 25,
15, 47, 7, 39, 13, 45, 5, 37,
63, 31, 55, 23, 61, 29, 53, 21};
unsigned char huge *pd;
unsigned char *pr, *linebuffer;
unsigned long size;
unsigned int ditherlinewidth;
unsigned int a, i, j, n, x;
ditherlinewidth = pixels2bytes(bmp.biWidth) << 2;
if(ditherlinewidth & 0x003) ditherlinewidth = (ditherlinewidth | 3) + 1;
size = (long)ditherlinewidth * (long)(bmp.biHeight + 1);
if((dh = GlobalAlloc(GMEM_MOVEABLE, size)) == NULL) return(MEM_ERR);
if((pd = GlobalLock(dh)) == NULL) {
GlobalFree(dh);
return(MEM_ERR);
}
if((linebuffer = (char *)malloc((short)bmp.biWidth * 3)) == NULL) {
GlobalUnlock(dh);
GlobalFree(dh);
return(MEM_ERR);
}
for(i = 0; i < bmp.biHeight; ++i) {
pr = linebuffer;
if(bmp.biBitCount == 4) {
for(j = x = 0; j < bmp.biWidth;) {
n = (gptr[(bmp.biHeight - i - 1) * linewidth + x] & 0x00f0) >> 4;
memcpy(pr, palette + n * 3, 3);
pr += 3;
++j;
if(j < bmp.biWidth) {
n = gptr[(bmp.biHeight - i - 1) * linewidth + x] & 0x000f;
memcpy(pr, palette + n * 3, 3);
pr += 3;
}
++j;
++x;
}
}
if(bmp.biBitCount == 8)
for(j = 0; j < bmp.biWidth; ++j) {
n = gptr[(bmp.biHeight - i - 1) * linewidth + j] & 0xff;
memcpy(pr, palette + n * 3, 3);
pr += 3;
}
if(bmp.biBitCount == 24)
for(j = 0; j < bmp.biWidth; ++j) {
pr[0] = gptr[(bmp.biHeight - i - 1) * linewidth + j * 3 + 2];
pr[1] = gptr[(bmp.biHeight - i - 1) * linewidth + j * 3 + 1];
pr[2] = gptr[(bmp.biHeight - i - 1) * linewidth + j * 3];
pr += 3;
}
pr = linebuffer;
for(j = x = 0; j < bmp.biWidth;) {
a = bayerpattern[i & 0x0007][j & 0x0007] << 2;
n = 0;
if(pr[0] > a) n |= 0x01;
if(pr[1] > a) n |= 0x02;
if(pr[2] > a) n |= 0x04;
pr += 3;
pd[(bmp.biHeight - i - 1) * ditherlinewidth + x] = ((n << 4) & 0x00f0);
++j;
if(j < bmp.biWidth) {
a = bayerpattern[i & 0x0007][j & 0x0007] << 2;
n = 0;
if(pr[0] > a) n |= 0x01;
if(pr[1] > a) n |= 0x02;
if(pr[2] > a) n |= 0x04;
pr += 3;
pd[(bmp.biHeight - i - 1) * ditherlinewidth + x] |= (n & 0x000f);
}
++j;
++x;
}
}
free(linebuffer);
linewidth = ditherlinewidth;
bmp.biBitCount = picbits = 4;
bmpi.bmiHeader = bmp;
GlobalUnlock(dh);
memcpy(palette, fixedpalette, 24);
return(0);
}
long motr2intellng(long ml, int tf) {
if(tf) return(ml);
return(((ml & 0xff000000L) >> 24) +
((ml & 0x00ff0000L) >> 8) +
((ml & 0x0000ff00L) << 8) +
((ml & 0x000000ffL) << 24));
}
int motr2intelint(int ml, int tf) {
if(tf) return(ml);
return(((ml & 0xff00) >> 8) +
((ml & 0xff) << 8));
}
unsigned int GetMIw(FILE *fp, int tf)
{
if(tf) return((fgetc(fp) & 0xff) + ((fgetc(fp) & 0xff) << 8));
else return(((fgetc(fp) & 0xff) << 8) + (fgetc(fp) & 0xff));
}
unsigned long GetMIlng(FILE *fp, int tf)
{
if(tf)
return(((unsigned long)(fgetc(fp) & 0xff) << 24) +
((unsigned long)(fgetc(fp) & 0xff) << 16) +
((unsigned long)(fgetc(fp) & 0xff) << 8) +
(unsigned long)(fgetc(fp) & 0xff));
else
return((unsigned long)(fgetc(fp) & 0xff) +
((unsigned long)(fgetc(fp) & 0xff) << 8) +
((unsigned long)(fgetc(fp) & 0xff) << 16) +
((unsigned long)(fgetc(fp) & 0xff) << 24));
}